package ru.sgu.diploma.practic.utils;

import ru.sgu.diploma.practic.errors.AlphabetExcephion;
import ru.sgu.diploma.practic.errors.NextLetterException;

import java.util.LinkedList;
import java.util.List;
import java.util.Set;

/**
 * User: datmakin
 * Date: 14.03.11
 * Email: atmakin.dv@gmail.com
 */
public class AutomatUtils {
    public static List<String[]> calculateSequencies(String[] alphabet, Integer size) throws AlphabetExcephion, NextLetterException {
        List<String[]> result = new LinkedList<String[]>();
        Integer power = alphabet.length;


        String[] present = new String[size];
        if (power < 1)
            throw new AlphabetExcephion("");

        for (int i = 0; i < size; i++)
            present[i] = alphabet[0];

        result.add(present);

        if (power == 1) {
            result.add(present);
            return result;
        }

        String[] end = new String[size];
        for (int i = 0; i < size; i++)
            end[i] = alphabet[power - 1];

        while (!isEnd(present, end)) {
            present = calculateNext(alphabet, size - 1, present, 0);
            result.add(present);
        }

        return result;
    }

    private static boolean isEnd(String[] present, String[] end) {
        for (int i = 0; i < present.length; i++)
            if (!present[i].equals(end[i]))
                return false;
        return true;
    }

    private static String[] calculateNext(String[] alphabet, Integer size, String[] prev, Integer grade) throws NextLetterException {
        String[] present = new String[prev.length];
        for (int i = 0; i < present.length; i++)
            present[i] = prev[i];
        String letter = present[size - grade];
        if (letter.equals(alphabet[alphabet.length - 1])) {
            present[size - grade] = alphabet[0];
            present = calculateNext(alphabet, size, present, grade + 1);
        } else {
            present[size - grade] = nextLetter(letter, alphabet);
        }

        return present;
    }


    private static String nextLetter(String little, String[] alphabet) throws NextLetterException {
        for (int i = 0; i < alphabet.length; i++) {
            if (little.equals(alphabet[i]))
                return alphabet[i + 1];
        }
        throw new NextLetterException("");
    }
}
